//-----------------------------------------------------------------------------
//  File          : apmconfig.c
//  Module        :
//  Description   : APM Configuration Functions.
//  Author        : Lewis
//  Notes         : N/A
//
// ============================================================================
// | Naming conventions                                                       |
// | ~~~~~~~~~~~~~~~~~~                                                       |
// |         Struct/Array : Leading s                                         |
// |             Constant : Leading K                                         |
// |      Global Variable : Leading g  (variable use outside one C file)      |
// |                                                                          |
// |   BYTE( 8 Bits) size : Leading b                                         |
// |   CHAR( 8 Bits) size : Leading c                                         |
// |   WORD(16 Bits) size : Leading w                                         |
// |  DWORD(32 Bits) size : Leading d                                         |
// |    int(32 Bits) size : Leading i                                         |
// | DDWORD(64 Bits) size : Leading dd                                        |
// |              Pointer : Leading p                                         |
// |                                                                          |
// |    Function argument : Leading a                                         |
// |       Local Variable : All lower case                                    |
// |                                                                          |
// | Examples:                                                                |
// |                Array : Leading s, (sb = arrary of byte, etc)             |
// |              Pointer : Leading p, (pb = pointer of byte, etc)            |
// ============================================================================
//
//  Date          Who         Action
//  ------------  ----------- -------------------------------------------------
//  01 Apr  2009  Lewis       Initial Version.
//-----------------------------------------------------------------------------
#include <string.h>
#include "midware.h"
#include "sysutil.h"
#include "kbdutil.h"
#include "rmenu.h"
#if (T800)
#include "cfgicon.h"
#endif
#include "message.h"
#include "toggle.h"
#include "comm.h"
#include "stis.h"
#include "termdata.h"
#include "inittran.h"
#include "hardware.h"
#include "apmconfig.h"

//-----------------------------------------------------------------------------
//      Defines
//-----------------------------------------------------------------------------
enum {
  CFG_DISP,
  CFG_KBDBL,
  CFG_TERMIP,
  CFG_DHCP,
  CFG_GPRS,
  CFG_DATE,
  CFG_TERM,
  CFG_TRAINING,
  MAX_CONFIG_ITEM,
};

enum {
  STIS_SETUP=0,
  STIS_INIT,
  STIS_SHOW,
  STIS_PRINT,
  MAX_STIS_ITEM,
};


//-----------------------------------------------------------------------------
//      Globals
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
//      Constants
//-----------------------------------------------------------------------------
static struct RMENUDAT KConfigMenu[MAX_CONFIG_ITEM+1] =
{
  { CFG_DISP,     "Lcd "      }, // extra space for current mark
#if (T800)
  { CFG_KBDBL,    "Kbd "      },
#endif
  { CFG_GPRS,     "GPRS "     },
  { CFG_DATE,     "DateTime " },
  { CFG_TERMIP,   "TermIP "   },
  { CFG_DHCP,     "DHCP "     },
  { CFG_TERM,     "TermData " },
  { CFG_TRAINING, "Training " },
  { -1,           ""          },
};

static struct RMENUDAT KStisMenu[MAX_STIS_ITEM+1] =
{
  { STIS_SETUP,   "Setup "     }, // extra space for current mark
  { STIS_INIT,    "Init "      },
  { STIS_SHOW,    "Show "      },
  { STIS_PRINT,   "Print "     },
  { -1,           ""           },
};
#if (R700|T800)
//*****************************************************************************
//  Function        : LcdSetup
//  Description     : Setup display's parameters.
//  Input           : N/A
//  Return          : N/A
//  Note            : N/A
//  Globals Changed : N/A
//*****************************************************************************
static void LcdSetup(void)
{
  BYTE tmpbuf[MW_MAX_LINESIZE+1];
  DWORD keyin;
  BYTE level, timeout;

  GetSysCfgMW(MW_SYSCFG_LCDB, &level);
  GetSysCfgMW(MW_SYSCFG_LCDTIMEOUT, &timeout);
  DispLineMW("BRIGHTNESS       BUp", MW_LINE1, MW_CLRDISP|MW_BIGFONT);
  DispLineMW("BDn", MW_LINE3, MW_RIGHT|MW_BIGFONT);
  DispLineMW("TIMEOUT          TUp", MW_LINE5, MW_BIGFONT);
  DispLineMW("TDn", MW_LINE7, MW_RIGHT|MW_BIGFONT);
  sprintf(tmpbuf, "[%02d]", level);
  DispLineMW(tmpbuf, MW_LINE3+4, MW_BIGFONT);
  sprintf(tmpbuf, "[%02d]", timeout);
  DispLineMW(tmpbuf, MW_LINE7+4, MW_BIGFONT);

  keyin = 0;
  do {
    SleepMW();
    keyin = GetCharMW();
    if (keyin == 0)
      continue;
    switch (keyin) {
      case MWKEY_RIGHT1:
        level += (level < 7) ? 1: 0;
        DispBrightMW(level);
        break;
      case MWKEY_RIGHT2:
        level -= (level > 0) ? 1: 0;
        DispBrightMW(level);
        break;
      case MWKEY_RIGHT3:
        if (timeout < 245)
          timeout += 10;
        else
          timeout = 255;
        DispBLCtrlMW(timeout);
        break;
      case MWKEY_RIGHT4:
        if (timeout > 10)
          timeout -= 10;
        else
          timeout = 0;
        DispBLCtrlMW(timeout);
        break;
    }
    sprintf(tmpbuf, "[%02d]", level);
    DispLineMW(tmpbuf, MW_LINE3+4, MW_BIGFONT);
    sprintf(tmpbuf, "[%02d]", timeout);
    DispLineMW(tmpbuf, MW_LINE7+4, MW_BIGFONT);
  } while (keyin != MWKEY_CANCL);
}
#endif
#if (PR608|TIRO)
//*****************************************************************************
//  Function        : LcdSetup
//  Description     : Adjust Lcd's contrast.
//  Input           : N/A
//  Return          : N/A
//  Note            : N/A
//  Globals Changed : N/A
//*****************************************************************************
static void LcdSetup(void)
{
#define MAX_CONTRAST      63
  BYTE  buf[128];
  DWORD value, max_value;
  DWORD keyin;

  DispLineMW("LCD Contrast", MW_LINE1, MW_CLRDISP|MW_REVERSE|MW_CENTER|MW_SPFONT); 

  GetSysCfgMW(MW_SYSCFG_LCDCONTRAST, buf);
  value     = buf[0];
  max_value = MAX_CONTRAST;
  keyin = 0;
  do {
    if ((keyin == MWKEY_ENTER) && (value < max_value))
      value++;
    if ((keyin == MWKEY_CLR) && (value > 0))
      value--;

    if ((keyin == MWKEY_ENTER) || (keyin == MWKEY_CLR) || (keyin == 0)) {
      os_disp_cont(value);
      sprintf(buf, "Level: %03d", value);
      DispLineMW(buf, MW_LINE4, MW_BIGFONT);
      DispLineMW("+:<Enter> -:<Clear>", MW_LINE7, MW_CENTER|MW_SPFONT);
    }
    keyin = 0x00;
    SleepMW();
  } while ((keyin=GetCharMW()) != MWKEY_CANCL);

  PutSysCfgMW(MW_SYSCFG_LCDCONTRAST, &value);
  UpdSysCfgMW();
}
#endif
#if (T800)    
//*****************************************************************************
//  Function        : KbdBacklight
//  Description     : Toggle Keyboard Backlight control
//  Input           : N/A
//  Return          : N/A
//  Note            : N/A
//  Globals Changed : N/A
//*****************************************************************************
static void KbdBacklight(void)
{
  BYTE kbdbl, cur_val;

  GetSysCfgMW(MW_SYSCFG_KBDBL, &kbdbl);
  DispLineMW(KKbdBacklight, MW_LINE3, MW_CLRDISP|MW_BIGFONT);

  cur_val = ToggleOption(NULL, KEnable, kbdbl|TOGGLE_MODE_4LINE);
  if ((cur_val != kbdbl) && (cur_val != 0xFF))  {
    kbdbl = cur_val;
    PutSysCfgMW(MW_SYSCFG_KBDBL, &kbdbl);
    UpdSysCfgMW();
  }
}
#endif // (T800)
//*****************************************************************************
//  Function        : DispTermIP
//  Description     : Display terminal ip, netmask, gateway ip.
//  Input           : aIP;      // pointer to ip info.
//  Return          : N/A
//  Note            : N/A
//  Globals Changed : N/A
//*****************************************************************************
void DispTermIP(BYTE *aIP)
{
  DispClrBelowMW(MW_LINE2);
  DispLineMW("IP Address", MW_LINE2, MW_SMFONT);
  ShowIp(aIP, MW_LINE3, FALSE);
  DispLineMW("Netmask", MW_LINE4, MW_SMFONT);
  ShowIp(&aIP[4], MW_LINE5, FALSE);
  DispLineMW("Gateway IP", MW_LINE6, MW_SMFONT);
  ShowIp(&aIP[8], MW_LINE7, FALSE);
}
//*****************************************************************************
//  Function        : ConfigTermIP
//  Description     : Setup ip, netmask, gateway ip
//  Input           : aIP;      // pointer to ip info.
//  Return          : N/A
//  Note            : N/A
//  Globals Changed : N/A
//*****************************************************************************
static BOOLEAN ConfigTermIP(BYTE *aIP)
{
  DispLineMW(KIpHdr, MW_LINE1, MW_CLRDISP|MW_REVERSE|MW_CENTER|MW_SMFONT);
  DispTermIP(aIP);

  if (!EditIp(aIP, MW_LINE3))
    return FALSE;

  if (!EditIp(&aIP[4], MW_LINE5))
    return FALSE;

  if (!EditIp(&aIP[8], MW_LINE7))
    return FALSE;

  DispLineMW(KEnterSave, MW_LINE8, MW_REVERSE|MW_CLREOL|MW_CENTER|MW_SPFONT);

  if (WaitKey(KBD_TIMEOUT) != MWKEY_ENTER)
    return FALSE;

  return TRUE;
}
//*****************************************************************************
//  Function        : ToggleDHCP
//  Description     : Toggle DHCP setting
//  Input           : aDHCP;            // current DHCP setting
//                    aIP;              // current IP config
//  Return          : TRUE/FALSE;       // TRUE => state changed.
//  Note            : N/A
//  Globals Changed : N/A
//*****************************************************************************
static BOOLEAN ToggleDHCP(BYTE *aDHCP, BYTE *aIP)
{
  BOOLEAN ret;
  BYTE  cur_val;

  ret = FALSE;

  DispLineMW(KDHCPHdr, MW_LINE1, MW_CLRDISP|MW_REVERSE|MW_CENTER|MW_SMFONT);
  DispTermIP(aIP);

  cur_val = ToggleOption(NULL, KEnable, *aDHCP|TOGGLE_MODE_8LINE);
  if ((cur_val != *aDHCP) && (cur_val != 0xFF))  {
    *aDHCP = cur_val;
    ret = TRUE;
  }
  return ret;
}
//*****************************************************************************
//  Function        : PromptReboot
//  Description     : Prompt user to reboot after save config.
//  Input           : N/A
//  Return          : N/A
//  Note            : N/A
//  Globals Changed : N/A
//*****************************************************************************
static void PromptReboot(void)
{
  Disp2x16Msg(KReboot, MW_LINE3, MW_CLRDISP|MW_BIGFONT);
  if (WaitKey(KBD_TIMEOUT) == MWKEY_ENTER) {
    ResetMW();
  }
}

void TermIPFunc(void)
{
  BYTE    ip[12];

  GetSysCfgMW(MW_SYSCFG_IP,      &ip[0]);
  GetSysCfgMW(MW_SYSCFG_NETMASK, &ip[4]);
  GetSysCfgMW(MW_SYSCFG_GATEWAY, &ip[8]);

  if(ConfigTermIP(ip))
  {
    PutSysCfgMW(MW_SYSCFG_IP, &ip[0]);
    PutSysCfgMW(MW_SYSCFG_NETMASK, &ip[4]);
    PutSysCfgMW(MW_SYSCFG_GATEWAY, &ip[8]);
    UpdSysCfgMW();
    PromptReboot();
  }
}

//*****************************************************************************
//  Function        : SetDate
//  Description     : Set System Date/Time.
//  Input           : N/A
//  Return          : N/A
//  Note            : N/A
//  Globals Changed : N/A
//*****************************************************************************
static void SetDate(void)
{
  BYTE kbdbuf[MAX_INPUT_LEN+1];

  // rtc setting
  RtcGetMW(kbdbuf);
  DispLineMW(KDateTime, MW_LINE3, MW_CLRDISP|MW_BIGFONT);
  kbdbuf[14] = 0;
  DispLineMW(kbdbuf, MW_LINE5, MW_BIGFONT);
  kbdbuf[0] = 0;
  if (!GetKbd(NUMERIC_INPUT+MW_BIGFONT+MW_LINE7+RIGHT_JUST, IMIN(14)+IMAX(14), kbdbuf))
    return;
  if (kbdbuf[0]) {
    RtcSetMW(&kbdbuf[1]);
    RtcGetMW(kbdbuf);
    kbdbuf[14] = 0;
    DispClrBelowMW(MW_LINE5);
    DispLineMW(kbdbuf, MW_LINE5, MW_BIGFONT);
    DispLineMW(KUpdated, MW_LINE7, MW_RIGHT|MW_BIGFONT);
    Short2Beep();
    Delay1Sec(2, 0);
  }
}
//*****************************************************************************
//  Function        : ApmConfig
//  Description     : Process Configuration selection.
//  Input           : N/A
//  Return          : N/A
//  Note            : N/A
//  Globals Changed : N/A
//*****************************************************************************
void ApmConfig(void)
{
  int select;
  struct MW_NIF_INFO netinfo;
  BYTE    dhcp;
  BYTE    ip[12];
  BOOLEAN reboot_required;
#if (T800)
  BYTE    bl_timeout;

  GetSysCfgMW(MW_SYSCFG_LCDTIMEOUT, &bl_timeout);
#endif
  while (1) {
#if (T800)
    select = RMenuSel(KConfigMenu, KCfgIcon, "\x0E\x10\x1B\x06\x03SETUP\x0F");
#else
    select = RMenuSel(KConfigMenu, NULL, NULL);
#endif
    if (select == -1)
      return;

    if ((select == CFG_TERMIP) || (select == CFG_DHCP)) {
      GetSysCfgMW(MW_SYSCFG_DHCP_ENABLE, &dhcp);
      if (dhcp) {
        NetInfoMW(MW_NIF_ETHERNET, &netinfo);
        memcpy(ip, (BYTE *)&netinfo.d_ip, 12);
      }
      else {
        GetSysCfgMW(MW_SYSCFG_IP,      &ip[0]);
        GetSysCfgMW(MW_SYSCFG_NETMASK, &ip[4]);
        GetSysCfgMW(MW_SYSCFG_GATEWAY, &ip[8]);
      }
    }
#if (T800)    
    if (select != CFG_DISP)
      DispBLCtrlMW(0xFF);  // Disable Backlight auto off
#endif    
    reboot_required = FALSE;
    switch (select) {
      case CFG_DISP:
        LcdSetup();
        break;
#if (T800)
      case CFG_KBDBL:
        KbdBacklight();
        break;
#endif
      case CFG_TERMIP:
        if (ConfigTermIP(ip))
          reboot_required=TRUE;
        break;
      case CFG_DHCP:
        if (ToggleDHCP(&dhcp, ip))
          reboot_required=TRUE;
        break;
      case CFG_GPRS:
        DispLineMW(KGPRSHdr, MW_LINE1, MW_CLRDISP|MW_REVERSE|MW_CENTER|MW_BIGFONT);
        SetGPRS();
        break;
      case CFG_DATE:
        SetDate();
        break;
      case CFG_TERM:
        SetupTerm();
        break;
      case CFG_TRAINING:
        DispLineMW("SET TRAINING", MW_LINE1, MW_CLRDISP|MW_REVERSE|MW_CENTER|MW_BIGFONT);
        if (GetAccessCode())
          SetModeOnOff(TOGGLE_TRAINING);
        break;
      default:
        DispLineMW("TEST TBD!", MW_LINE3, MW_CLRDISP|MW_REVERSE|MW_CENTER|MW_BIGFONT);
        WaitKey(KBD_TIMEOUT);
    }
#if (T800)    
    if (select != CFG_DISP)
      DispBLCtrlMW(bl_timeout);  // restore bl control timer
#endif    

    // Save Term IP information and reboot
    if (reboot_required) {
      PutSysCfgMW(MW_SYSCFG_DHCP_ENABLE, &dhcp);
      PutSysCfgMW(MW_SYSCFG_IP, &ip[0]);
      PutSysCfgMW(MW_SYSCFG_NETMASK, &ip[4]);
      PutSysCfgMW(MW_SYSCFG_GATEWAY, &ip[8]);
      UpdSysCfgMW();
      PromptReboot();
    }
  } // while (1);
}
//*****************************************************************************
//  Function        : STISConfig
//  Description     : Process STIS related operation.
//  Input           : N/A
//  Return          : N/A
//  Note            : N/A
//  Globals Changed : N/A
//*****************************************************************************
void STISConfig(void)
{
  int select;

  while (1) {
#if (T800)
    select = RMenuSel(KStisMenu, KCfgIcon, "\x0E\x10\x1B\x06\x03SETUP\x1B\x07\x04STIS\x0F");
#else
    select = RMenuSel(KStisMenu, NULL, NULL);
#endif
    if (select == -1)
      return;

    switch (select) {
      case STIS_SETUP:
        SetupSTIS();
        break;
      case STIS_INIT:
        InitTrans();
        break;
      case STIS_SHOW:
        PrintSTIS(TRUE, TRUE);
        break;
      case STIS_PRINT:
        PrintSTIS(TRUE, FALSE);
        break;
    }
  } // while (1);
}
